/*****************************************************************************
*    Copyright (C)2003 Ali Corporation. All Rights Reserved.
*
*    File:    nim_sl1935.c
*
*    Description:    This file contains sl1935 basic function in LLD.
*    History:
*           Date            Athor        Version          Reason
*	    ============	=============	=========	=================
*	1.	Jun.12.2003     George jiang     Ver 0.1    Create file.
*	2.  Aug.25.2003		Justin Wu		 Ver 0.2	Re-coding.
*	3.  08/31/2005	Zhu Jun		Ver 0.3		Unify Tuner's configuration API Functions
*
*****************************************************************************/

#include <sys_config.h>
#include <retcode.h>
#include <types.h>

#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <bus/i2c/i2c.h>

#include "nim_sl1935.h"

struct QPSK_TUNER_CONFIG_EXT * stSL1935_dev_id[MAX_TUNER_SUPPORT_NUM] = {NULL};
static UINT32 stSL1935_tuner_cnt = 0;
/*****************************************************************************
* INT32 nim_sl1935_init(UINT32 para, struct QPSK_TUNER_CONFIG_EXT * ptrTuner_Config)
*
* Tuner SL1935 Initialization
*
* Arguments:
*  Parameter1: UINT32 para		: Input Parameter
*  Parameter2: struct QPSK_TUNER_CONFIG_EXT * ptrTuner_Config		: pointer for Tuner configuration structure
*
* Return Value: INT32			: Result
*****************************************************************************/
INT32 nim_sl1935_init(UINT32 * tuner_id, struct QPSK_TUNER_CONFIG_EXT * ptrTuner_Config)
{
	struct QPSK_TUNER_CONFIG_EXT * stSL1935_ptr = NULL;
	/* check Tuner Configuration structure is available or not */
	if (ptrTuner_Config == NULL||stSL1935_tuner_cnt>=MAX_TUNER_SUPPORT_NUM)
		return ERR_FAILUE;
	stSL1935_ptr = (struct QPSK_TUNER_CONFIG_EXT*)MALLOC(sizeof(struct QPSK_TUNER_CONFIG_EXT));
	if(!stSL1935_ptr)
		return ERR_FAILUE;
	stSL1935_dev_id[stSL1935_tuner_cnt] = stSL1935_ptr;
	MEMCPY(stSL1935_ptr, ptrTuner_Config, sizeof(struct QPSK_TUNER_CONFIG_EXT));
	*tuner_id = stSL1935_tuner_cnt;
	stSL1935_tuner_cnt ++;
/*	soc_printf("%s: sizeof QPSK_TUNER_CONFIG_EXT = %d\n", __FUNCTION__, sizeof(struct QPSK_TUNER_CONFIG_EXT));
	soc_printf("Base Address: 0x%x\n",stSL1935_Config.cTuner_Base_Addr);
	soc_printf("Tuner Crystal: %dKHz\n",stSL1935_Config.wTuner_Crystal);
	soc_printf("Output Mode: %d (1 -- Signle End; 0 -- Differential)\n",stSL1935_Config.cTuner_Out_S_D_Sel);
*/
	return SUCCESS;
}

/*****************************************************************************
* INT32 nim_sl1935_control(UINT32 freq, UINT32 sym)
*
* Tuner write operation
*
* Arguments:
*  Parameter1: UINT32 freq		: Synthesiser programmable divider
*  Parameter2: UINT32 bs			: Baseband Symbol Rate
*
* Return Value: INT32			: Result
*****************************************************************************/
INT32 nim_sl1935_control(UINT32 tuner_id, UINT32 freq, UINT32 sym)
{
	UINT8 data[4];
	UINT8 pos;
	UINT16 divider;
	UINT8 bs;
	struct QPSK_TUNER_CONFIG_EXT * stSL1935_ptr = NULL;
	
	if (tuner_id>=stSL1935_tuner_cnt||tuner_id>=MAX_TUNER_SUPPORT_NUM)
		return ERR_FAILUE;
	stSL1935_ptr = stSL1935_dev_id[tuner_id];
	if (sym == 0)
		sym = 45000;

	bs = sym < 6500 ? 1 : 0;	/* Symbol rate is less than 6.5M, low symbol rate */

	pos = (freq > 1500 ? 1 : 0);
	divider = (freq * 16000 + 1000) / 2000;						/* 125K step */

	data[0] = (UINT8)((divider >> 8) & 0x7f);
	data[1] = (UINT8)divider;
#if 0
	/* Zarlink Standard NIM Spec */
	data[2] = (UINT8)((pos ? 0x24 : 0x04) | 0x80);				/* pos->Pump */
	data[3] = (UINT8)((pos ? 0x00 : 0x10) | ((bs & 1) << 3));	/* pos->vs, bs->bs */
#else

	if (stSL1935_ptr->wTuner_Crystal == 10000)
		data[2] = (UINT8)0xCD;										/* 80div@10M */
	else
		/* TONGTEL & EARDA NIM Spec */
		data[2] = (UINT8)0xC4;										/* 32div@4M */

	//if( 1 == bs )
	//	data[3] = (UINT8)((pos ? 0x08 : 0x18));
	//else
		data[3] = (UINT8)((pos ? 0x00 : 0x10));						/* pos -> vs */
#endif

	return i2c_write(stSL1935_ptr->i2c_type_id, stSL1935_ptr->cTuner_Base_Addr, data, 4);

}

/*****************************************************************************
* INT32 nim_sl1935_status(UINT8 *lock)
*
* Tuner read operation
*
* Arguments:
*  Parameter1: UINT8 *lock		: Phase lock status
*
* Return Value: INT32			: Result
*****************************************************************************/
INT32 nim_sl1935_status(UINT32 tuner_id, UINT8 *lock)
{
	INT32 result;
	UINT8 data;
	struct QPSK_TUNER_CONFIG_EXT * stSL1935_ptr = NULL;
	if (tuner_id>=stSL1935_tuner_cnt||tuner_id>=MAX_TUNER_SUPPORT_NUM)
	{
		*lock = 0;
		return ERR_FAILUE;
	}
	stSL1935_ptr = stSL1935_dev_id[tuner_id];
	result = i2c_read(stSL1935_ptr->i2c_type_id, stSL1935_ptr->cTuner_Base_Addr, &data, 1);
	*lock = ((data & 0x40) >> 6);

	return result;
}

